package com.ruoyi.system.amqp;

import com.google.gson.Gson;

import com.alibaba.fastjson2.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.iot.model.v20180120.*;
import com.aliyuncs.profile.DefaultProfile;
import com.ruoyi.system.LineGlobalConfig;
import com.ruoyi.system.service.ILineDeviceService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;


@Component
public class AmqpMessagePub {

    @Autowired
    ILineDeviceService iLineDeviceService;

    private final static Logger logger = LoggerFactory.getLogger(AmqpMessagePub.class);

    DefaultProfile profile = DefaultProfile.getProfile("cn-shanghai",
            System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));

    IAcsClient client = new DefaultAcsClient(profile);



    private final TaskExecutor taskExecutor;

    @Autowired
    public AmqpMessagePub(TaskExecutor taskExecutor) {
        this.taskExecutor = taskExecutor;
    }

    public void publishManyMessage(String productKey, String deviceName, String messageContent, int monitorTime, int intervalInMs) {
        int retries = 0;
        int count = (int)(monitorTime*1000.0 / intervalInMs);
        if(count > 0){for(int i = 0; i < count; i++){
                int ret = publishMessage(productKey, deviceName, messageContent);
                if (ret == 1 && retries < 3) {
                    logger.warn("消息发布失败，正在尝试重新发送......");
                    count++;
                    retries++;
                } else if (retries > 3) {
                    logger.error("消息发布失败，已达到最大重试次数，停止发送!");
                    break;
                } else {
                    retries = 0;
                    logger.info("第"+(i+1)+"条"+"设备消息发布成功");
                }
                try {
                    Thread.sleep(intervalInMs);
                } catch (InterruptedException e) {
                    logger.warn("线程被中断，可能停止消息发布", e);
                }
            }
        }
    }


    @Async
    public void publishManyMessageAsync
            (final String productKey, final String deviceName, final String messageContent, final int monitorTime, final int intervalInMs) {
        taskExecutor.execute(() -> {
            publishManyMessage(productKey, deviceName, messageContent, monitorTime, intervalInMs);
        });
    }


    public int publishMessage(String productKey, String deviceName, String messageContent) {
        PubRequest request = new PubRequest();
        request.setIotInstanceId("iot-06z00hpv0v1sqpl");
        request.setProductKey(productKey);
        String topic = "/sys/" + productKey + "/" + deviceName + "/thing/service/property/set"; //
        request.setTopicFullName(topic);
        request.setMessageContent(messageContent);
        try {
            PubResponse response = client.getAcsResponse(request);
            JSONObject jsonObject =  JSONObject.parseObject(new Gson().toJson(response));
            boolean success = jsonObject.getBoolean("success");
            if(!success){
                logger.error(new Gson().toJson(response));
            } else {
                logger.info("["+deviceName+"]设备消息发布成功");
            }
            return success ? LineGlobalConfig.MSG_SUCCESS_CODE : LineGlobalConfig.MSG_FAIL_CODE;
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            logger.error("ErrCode:" + e.getErrCode() + "\n" +
            "ErrMsg:" + e.getErrMsg() + "\n" +
            "RequestId:" + e.getRequestId());
        }
        return LineGlobalConfig.MSG_FAIL_CODE;
    }
}
